//
//  ResumeAppDelegate.m
//  Resume
//
//  Created by Jeffrey Palm on 11/9/09.
//  Copyright jeffpalm.com 2009. All rights reserved.
//

#import "ResumeAppDelegate.h"
#import "ResumeViewController.h"
#import "Track.h"
#import <MediaPlayer/MediaPlayer.h>

@interface ResumeAppDelegate (PrivateMethods)
- (Track*)createFakeTrack;
- (Track*)getTrackFromWeb:(NSString*)user;
@end

@implementation ResumeAppDelegate

#define USE_FAKE_TRACK FALSE

#define BASE_URL @"http://jeffpalm.com/resumeapp"


@synthesize window;
@synthesize viewController;

- (void)note:(NSString*)msg {
	NSLog(@"Note: %@", msg);
	[viewController setStatus:msg];
}

- (Track*)createFakeTrack {
	Track *track	= [[Track alloc] init];
	track.artist			= @"Far";
	track.track				= @"In 2 Again";
	track.album				= @"Water & Solutions";
	track.currentTime = 58;
	return track;
}

// Remove all the crap from a string, like quotes, spaces, etc
// This doesn't relaly urlencode, but my fucking internet is down, so I
// can't find out how to actually sanitize/urlencode a string in cocoa
- (NSString*)urlencode:(NSString*)input {
	if (input == nil) return input;
	input = [input stringByReplacingOccurrencesOfString:@"'"  withString:@""  ];
	input = [input stringByReplacingOccurrencesOfString:@"\"" withString:@""  ];
	input = [input stringByReplacingOccurrencesOfString:@"<"  withString:@""  ];
	input = [input stringByReplacingOccurrencesOfString:@">"  withString:@""  ];
	input = [input stringByReplacingOccurrencesOfString:@" "  withString:@"+" ];
	return input;
}

- (Track*)getTrackFromWeb:(NSString*)user {
	NSString	*urlString = [NSString stringWithFormat:@"%@/get.php?user=%@",BASE_URL,user];
	NSURL			*url = [NSURL URLWithString:urlString];
	NSString	*contents = [NSString stringWithContentsOfURL:url];
	if (contents == nil) {
		NSLog(@"Couldn't read from: %@", urlString);
		return nil;
	}
	NSArray		*parts = [contents componentsSeparatedByString:@"\n"];
	NSDictionary *values = [[[NSMutableDictionary alloc] init] autorelease];
	for (NSString *part in parts) {
		NSArray *keyValue = [part componentsSeparatedByString:@"\t"];
		if ([keyValue count] < 2) continue;
		[values setValue:[keyValue objectAtIndex:1] forKey:[keyValue objectAtIndex:0]];
	}
	NSLog(@"Have values: %@", values);
	Track *track	= [[Track alloc] init];
	track.artist			= [values valueForKey  :@"artist" ];
	track.track				= [values valueForKey  :@"track"  ];
	track.album				= [values valueForKey  :@"album"  ];
	track.currentTime = [[values valueForKey :@"time"   ] intValue];
	return track;
}
	
- (NSString*)getNewTrack:(NSString*)user {

	// Get the user's current song from the web
	Track *track;
	[self note:@"Getting track..."];
	if (USE_FAKE_TRACK) {
		track = [self createFakeTrack];
	} else {
		track = [self getTrackFromWeb:user];
	}
	if (track == nil) {
		NSLog(@"Couldn't create track");
		return @"Couldn't create track";
	}
	[self note:[NSString stringWithFormat:@"Have track: %@", track.track]];
	[viewController doneTask];
	
	NSLog(@"Have track");
	NSLog(@" - artist : %@", track.artist);
	NSLog(@" - album  : %@", track.album);
	NSLog(@" - track  : %@", track.track);
	NSLog(@" - time   : %d", track.currentTime);
	
	[self note:@"Searching for song..."];
	
	// Search for the song in the user's media library
	MPMediaPropertyPredicate *artistNamePredicate =	
	[MPMediaPropertyPredicate predicateWithValue: track.artist
																	 forProperty: MPMediaItemPropertyArtist];
	MPMediaPropertyPredicate *albumNamePredicate =
	[MPMediaPropertyPredicate predicateWithValue: track.album
																	 forProperty: MPMediaItemPropertyAlbumTitle];
	MPMediaPropertyPredicate *trackNamePredicate =
	[MPMediaPropertyPredicate predicateWithValue: track.track
																	 forProperty: MPMediaItemPropertyTitle];
	MPMediaQuery *exactQuery = [[MPMediaQuery alloc] init];
	[exactQuery addFilterPredicate: artistNamePredicate];
	[exactQuery addFilterPredicate:  albumNamePredicate];
	[exactQuery addFilterPredicate:  trackNamePredicate];
	
	NSArray *itemsExactQuery = [exactQuery items];
	[self note:[NSString stringWithFormat:@"Have %d item(s)", [itemsExactQuery count]]];
	
	MPMediaItem	*song;
	
	// If we don't have any items, try with just the artist
	if ([itemsExactQuery count] < 1) {
		MPMediaQuery *artistQuery = [[MPMediaQuery alloc] init];
		[artistQuery addFilterPredicate: artistNamePredicate];
		NSArray *itemsArtistQuery = [artistQuery items];
		[self note:[NSString stringWithFormat:@"Have %d item(s) from artist", [itemsArtistQuery count]]];
		if ([itemsArtistQuery count] > 0) {
			song = [itemsArtistQuery objectAtIndex:0];
		}
	} else {
		song = [itemsExactQuery objectAtIndex:0];
	}
	NSLog(@"Have song: %@", song);
	[viewController doneTask];
	
	if (song == nil) {
		return @"Couldn't find song";
	}
	
	[viewController noteSong:song];

	NSLog(@" - artist : %@", [song valueForProperty:MPMediaItemPropertyArtist]);
	NSLog(@" - album  : %@", [song valueForProperty:MPMediaItemPropertyAlbumTitle]);
	NSLog(@" - track  : %@", [song valueForProperty:MPMediaItemPropertyTitle]);
	
	// Start the media player with this song
	// Possibly, load the rest of this album
	MPMediaQuery *albumQuery = [[MPMediaQuery alloc] init];
	[albumQuery addFilterPredicate: artistNamePredicate];
	[albumQuery addFilterPredicate:  albumNamePredicate];	

	[self note:@"Playing song..."];
	MPMusicPlayerController *myPlayer = [MPMusicPlayerController iPodMusicPlayer];
	[myPlayer setQueueWithQuery: albumQuery];
	[myPlayer setNowPlayingItem:song];
	[myPlayer beginSeekingForward];
	[viewController doneTask];
	id totalTime = [song valueForProperty:MPMediaItemPropertyPlaybackDuration];
	NSLog(@"Total time: %@", totalTime);
	[self note:@"Seeking..."];
	while ([myPlayer currentPlaybackTime] < track.currentTime && [myPlayer currentPlaybackTime] < 500) {
		sleep(1);
	}
	[myPlayer endSeeking];
	[self note:@"Done seeking"];
	[viewController doneTask];
	[myPlayer play];
	
	// Success
	return nil;
}

- (NSString*)sendCurrentTrack:(NSString*)user {
	
	// Find the currently playing track
	[viewController startWorking:@"Looking for song"];
	MPMusicPlayerController *myPlayer = [MPMusicPlayerController iPodMusicPlayer];
	MPMediaItem *song = [myPlayer nowPlayingItem];
	
	// It's ok if we can't find one
	if (song == nil) {
		return @"Couldn't find playing song";
	}
	NSString *artist  = [song valueForProperty:MPMediaItemPropertyArtist];
	NSString *album   = [song valueForProperty:MPMediaItemPropertyAlbumTitle];
	NSString *track   = [song valueForProperty:MPMediaItemPropertyTitle];
	
	NSLog(@" - artist : %@", artist);
	NSLog(@" - album  : %@", album);
	NSLog(@" - track  : %@", track);
	[viewController doneTask];
	
	// If we have a track send this information with our user name
	[viewController startWorking:@"Sending song information"];
	int time = [myPlayer currentPlaybackTime];
	NSString	*urlString = [NSString stringWithFormat:@"%@/post.php?user=%@&track=%@&artist=%@&album=%@&time=%d",
													BASE_URL,
													[self urlencode:user],
													[self urlencode:track],
													[self urlencode:artist],
													[self urlencode:album],
													 time];
	NSURL			*url = [NSURL URLWithString:urlString];
	//NSString	*contents = 
	[NSString stringWithContentsOfURL:url];
	[viewController doneTask];
	
	// Pause the player
	[myPlayer pause];
	
	// Success
	return nil;
}

- (NSString*)doWork:(NSString*)user {
	
	[viewController startWorking:@"Starting..."];
	MPMusicPlayerController *myPlayer = [MPMusicPlayerController iPodMusicPlayer];
	if ([myPlayer playbackState] == MPMusicPlaybackStatePlaying) {
		return [self sendCurrentTrack:user];
	} else {
		return [self getNewTrack:user];
	}
}

- (void)setUserAndStart:(NSString*)user {
	[NSThread detachNewThreadSelector:@selector(doWorkThread:) toTarget:self withObject:user];		
}

- (void)doWorkThread:(NSString*)user {
	NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
	NSString *reason = [self doWork:user];
	int val = 0;
	if (reason != nil) {
		NSLog(@"ERROR:%@", reason);
		val = 1;
	}	
	[pool release];
	exit(val);
}

- (void)applicationDidFinishLaunching:(UIApplication *)application {    
	[window addSubview:viewController.view];
	[window makeKeyAndVisible];
	[viewController getUserAndStart];
}


- (void)dealloc {
	[viewController release];
	[window release];
	[super dealloc];
}


@end

